package com.zwd.cases.utils;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Description 常用方法封装工具类
 * @Author zhengwd
 * @Date 2022/5/13 10:47
 **/
@Slf4j
public class CommonUtil {

    public static void main(String[] args) {

        // =============================================================================日期常用方法-总结-begin
        // TODO 获取指定格式日期（年-月-日 时：分：秒）
//        String formatYmdHms = "yyyy-MM-dd HH:mm:ss";
//        String dateformatYmdHms = CommonUtil.date2Str(new Date(), formatYmdHms);
//        // 输出：2022-05-13 14:25:16
//        System.out.println(dateformatYmdHms);

        // TODO 获取指定格式日期（年-月-日）
//        String formatYmd = "yyyy-MM-dd";
//        String dateYmd = CommonUtil.date2Str(new Date(), formatYmd);
//        // 输出：2022-05-13
//        System.out.println(dateYmd);

        // TODO 时间String字符串 转 Date时间格式 yyyy-MM-dd HH:mm:ss
//        String formatYmdHmsStr = "2022-05-13 14:25:16";
//        Date ymdHmsDate = CommonUtil.strTimeToDateYmdHms(formatYmdHmsStr);
//        System.out.println(ymdHmsDate);

        // TODO 时间String字符串 转 Date时间格式 yyyy-MM-dd
//        String formatYmdStr = "2022-05-13";
//        Date ymdDate = CommonUtil.strTimeToDateYmd(formatYmdStr);
//        System.out.println(ymdDate);

        // TODO 获取yyyy-MM-dd HH:mm:ss格式的当前日期
//        String formatDateYmdHms = CommonUtil.formatDateYmdHms();
//        System.out.println(formatDateYmdHms);

        // TODO 获取yyyy-MM-dd格式的当前日期
//        String formatDateYmd = CommonUtil.formatDateYmd();
//        System.out.println(formatDateYmd);

        // TODO 计算两个时间相隔的天数（仅计算相差天数，不保留小数）
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//        try {
//            Date beginDate = format.parse("2007-12-24 0:30:00");
//            Date endDate = format.parse("2007-12-26 12:30:00");
//            System.out.println(beginDate);
//            System.out.println(endDate);
//            long day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
//            System.out.println("相隔的天数=" + day);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        // TODO 计算两个时间相隔的天数（保留一位小数）
//        String s1 = "2009-02-03 06:00:00";
//        String s2 = "2009-02-06 18:30:00";
//        try {
//            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//            double hour = (format.parse(s2).getTime() - format.parse(s1).getTime()) / 60000;
//            double day = hour/(60*24*1.0);
//            System.out.println(day);
//            // 表明四舍五入，保留1位小数
//            BigDecimal b = new BigDecimal(day);
//            float f1 = b.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
//            System.out.println(f1);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        // =============================================================================日期常用方法-总结-end


        // =============================================================================字符串常用方法-总结-begin
        // TODO 判断字符串是否为空
//        String strTest0011 = null;
//        String strTest0012 = "";
//        String strTest0013 = "null";
//        String strTest0014 = "zwd";
//        boolean resultTest0011 = CommonUtil.strIsEmptyOrNull(strTest0011);
//        boolean resultTest0012 = CommonUtil.strIsEmptyOrNull(strTest0012);
//        boolean resultTest0013 = CommonUtil.strIsEmptyOrNull(strTest0013);
//        boolean resultTest0014 = CommonUtil.strIsEmptyOrNull(strTest0014);
//        System.out.println(resultTest0011);
//        System.out.println(resultTest0012);
//        System.out.println(resultTest0013);
//        System.out.println(resultTest0014);

        // TODO 字符串非空处理
//        String strTest0021 = CommonUtil.dealNull(strTest0011);
//        String strTest0022 = CommonUtil.dealNull(strTest0012);
//        String strTest0023 = CommonUtil.dealNull(strTest0013);
//        String strTest0024 = CommonUtil.dealNull(strTest0014);
//        System.out.println(strTest0021);
//        System.out.println(strTest0022);
//        System.out.println(strTest0023);
//        System.out.println(strTest0024);
        // =============================================================================字符串常用方法-总结-end


        // =============================================================================一些Map和List常用方法-总结-begin
        // TODO 简单的List转Map，适用于 “编码-中文内容”一一对应的数据类型转Map
//        List<Map<String, Object>> dataList = new ArrayList<>();
//        Map<String, Object> map1 = new HashMap<>();
//        map1.put("code", "001");
//        map1.put("content", "zwd");
//        dataList.add(map1);
//        Map<String, Object> map2 = new HashMap<>();
//        map2.put("code", "002");
//        map2.put("content", "zzz");
//        dataList.add(map2);
//        // test001：List转Map
//        Map<String, Object> map = CommonUtil.transListToMap(dataList, "code", "content");
//        // test002：遍历map输出
//        CommonUtil.foreachStringObjectMapInfo(map, "code", "content");
//        // test003：获取指指定key的value值
//        String content = CommonUtil.getMapValueByKey(map, "001");
//        log.info("content={}", content);
//        // test004：Map的key和value全部转大写
//        Map<String, Object> toUpperKeyMap = CommonUtil.toUpperKey(map);
//        CommonUtil.foreachStringObjectMapInfo(toUpperKeyMap, "CODE", "CONTENT");
//        // test005：Map的key和value全部转小写
//        Map<String, Object> toLowerKeyMap = CommonUtil.toLowerKey(toUpperKeyMap);
//        CommonUtil.foreachStringObjectMapInfo(toLowerKeyMap, "code", "content");

//        // TODO Map<String, Object>类型转Map<String, String>类型
//        Map<String, Object> sourceMap = new HashMap<>();
//        sourceMap.put("name", "zwd");
//        sourceMap.put("sex", "1");
//        Map<String, String> targetMap = new HashMap<>();
//        CommonUtil.dataSourceMapToTargetMap(sourceMap, targetMap);
//        targetMap.put("love", "girls");
//        CommonUtil.foreach2StringMapInfo(targetMap, "key", "value");

        // =============================================================================一些Map和List常用方法-总结-end

    }

    /**
     * Map<String, Object>类型转Map<String, String>类型
     * @param sourceMap
     * @param targetMap
     */
    public static void dataSourceMapToTargetMap(Map<String, Object> sourceMap,
                                                Map<String, String> targetMap) {
        Set<Map.Entry<String, Object>> entries = sourceMap.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            if (!CommonUtil.strIsEmptyOrNull(entry.getValue())) {
                targetMap.put(entry.getKey(), entry.getValue()+"");
            } else {
                targetMap.put(entry.getKey(), null);
            }
        }
    }

    /**
     * 判断对象是否为空
     * @param obj
     * @return
     */
    public static boolean strIsEmptyOrNull(Object obj) {
        if (obj == null || "".equals(obj) || "null".equals(obj)) {
            return true;
        }
        return false;
    }

    /**
     * 校验字符串是否为数字
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 得到输入流
     * @param urlStr
     * @return
     * @throws IOException
     */
    public static InputStream getInputStream(String urlStr)
            throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 设置超时间为3秒
        conn.setConnectTimeout(5 * 1000);
        // 防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent",
                "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 得到输入流
        return conn.getInputStream();
    }

    /**
     * 字符串非空处理
     * @param str
     * @return
     */
    public static String dealNull(Object str) {
        return str == null ? "" : str + "";
    }

    /**
     * 获取IP
     * @param request
     * @return
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        String comma = ",";
        String localhost = "127.0.0.1";
        if (ip.contains(comma)) {
            ip = ip.split(",")[0];
        }

        if (localhost.equals(ip)) {
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException var5) {
                var5.printStackTrace();
            }
        }
        return ip;
    }

    /**
     * 日期转字符串
     * @param date 日期
     * @param format 时间格式
     * @return
     */
    public static String date2Str(Date date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(date);
    }

    /**
     * 获取yyyy-MM-dd HH:mm:ss格式的当前日期
     * @return
     */
    public static String formatDateYmdHms() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(new Date());
    }

    /**
     * 获取yyyy-MM-dd格式的当前日期
     * @return
     */
    public static String formatDateYmd() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(new Date());
    }

    /**
     * 时间字符串 转 时间格式 yyyy-MM-dd HH:mm:ss
     * @param strTime
     * @return
     */
    public static Date strTimeToDateYmdHms(String strTime) {
        if (!"".equals(strTime)) {
            try {
                return DateUtil.parse(strTime, "yyyy-MM-dd HH:mm:ss");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 时间字符串 转 时间格式 yyyy-MM-dd
     * @param strTime
     * @return
     */
    public static Date strTimeToDateYmd(String strTime) {
        if (!"".equals(strTime)) {
            try {
                return DateUtil.parse(strTime, "yyyy-MM-dd");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 遍历输出Map数据
     * @param map Map<String, Object>类型入参
     * @param showKeyName 显示输出的key名称
     * @param showValueName 显示输出的content名称
     */
    public static void foreachStringObjectMapInfo(Map<String, Object> map,
                                      String showKeyName, String showValueName) {
        Set<String> sets = map.keySet();
        for (String key : sets) {
            log.info("{}={},{}={}", showKeyName, key, showValueName, map.get(key));
        }
    }

    /**
     * 遍历输出Map数据
     * @param map Map<String, String>类型入参
     * @param showKeyName 显示输出的key名称
     * @param showValueName 显示输出的content名称
     */
    public static void foreach2StringMapInfo(Map<String, String> map,
                                      String showKeyName, String showValueName) {
        Set<String> sets = map.keySet();
        for (String key : sets) {
            log.info("{}={},{}={}", showKeyName, key, showValueName, map.get(key));
        }
    }

    /**
     * 遍历输出Map数据
     * @param map Map<String, Object>类型入参
     */
    public static void foreachStringObjectMapInfo(Map<String, Object> map) {
        Set<String> sets = map.keySet();
        for (String key : sets) {
            log.info("key={},value={}", key, map.get(key));
        }
    }

    /**
     * 遍历输出Map数据
     * @param map Map<String, String>类型入参
     */
    public static void foreach2StringMapInfo(Map<String, String> map) {
        Set<String> sets = map.keySet();
        for (String key : sets) {
            log.info("key={},value={}", key, map.get(key));
        }
    }

    /**
     * List转Map方法
     * @param dataList list数据
     * @param showKeyName 显示输出的key名称
     * @param showValueName 显示输出的content名称
     * @return
     */
    public static Map<String,Object> transListToMap(List<Map<String, Object>> dataList,
                                                    String showKeyName, String showValueName){
        Map<String,Object> codeMap = new HashMap<>();
        Map<String, Object> stringObjectMap;
        int len = dataList.size();
        for (int i = 0; i < len; i++) {
            stringObjectMap = dataList.get(i);
            codeMap.put(stringObjectMap.get(showKeyName)+"", stringObjectMap.get(showValueName));
        }
        return codeMap;
    }

    /**
     * 根据key获取Map中value的值
     * @param map
     * @param key
     * @return
     */
    public static String getMapValueByKey(Map<String, Object> map, String key){
        return map.get(key) == null ?"": map.get(key)+"";
    }

    /**
     * 将map中的所有key转化为大写
     * @param map
     * @return
     */
    public static Map<String, Object> toUpperKey(Map<String, Object> map) {
        Map<String, Object> resultMap = new HashMap<>();
        Set<String> sets = map.keySet();
        for (String key : sets) {
            resultMap.put(key.toUpperCase(), map.get(key));
        }
        return resultMap;
    }

    /**
     * 将map中的所有key转化为小写
     * @param map
     * @return
     */
    public static Map<String, Object> toLowerKey(Map<String, Object> map) {
        Map<String, Object> resultMap = new HashMap<>();
        Set<String> sets = map.keySet();
        for (String key : sets) {
            resultMap.put(key.toLowerCase(), map.get(key));
        }
        return resultMap;
    }
}
